﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using DarkAngels.WoW.Library.Interfaces;
using DarkAngels.WoW.Library.Network;
using DarkAngels.WoW.Library.Armory.Character;
using System.Xml;

namespace DarkAngels.WoW.Library.Armory.Guild
{
    public class Guild : AbstractDataClass
    {
        private const string XPATH_GUILD_INFO =                  "/page/guildInfo/guildHeader";
        private const string XPATH_GUILD_MEMBER_INFO =           "/page/guildInfo/guild/members";
        private const string XPATH_GUILD_CHARACTERS_INFO =       "/page/guildInfo/guild/members/character";

        #region Properties
        public String GuildUrl
        {
            get;
            private set;
        }
        public String GuildName
        {
            get;
            private set;
        }
        public String RealmName
        {
            get;
            private set;
        }
        private Faction m_faction = Faction.NotSet;
        public Faction Faction
        {
            get
            {
                return m_faction;
            }
            private set
            {
                m_faction = value;
            }
        }

        private Int32 m_memberCount = 0;
        public Int32 MemberCount
        {
            get
            {
                return m_memberCount;
            }
            private set
            {
                if (value >= 1)
                    m_memberCount = value;
            }
        }

        private List<Character.Character> m_memberList = null;
        public List<Character.Character> Members
        {
            get
            {
                return m_memberList;
            }
        }

        #region Network- & data-properties
        /// <summary>
        /// The filename with paramters to call on the webserver. 
        /// Read-only based on CharacterName and RealmName properties.
        /// </summary>
        public String FileName
        {
            get
            {
                if (GuildUrl != null && GuildUrl.Length > 0)
                    return String.Format("guild-info.xml?{0}&p={1}", GuildUrl, CurrentPage);
                else
                    return String.Format("guild-info.xml?r={0}&n={1}&p={2}", RealmName, GuildName, CurrentPage);
            }
        }

        private Int32 m_currentPage = 1;
        public Int32 CurrentPage
        {
            get
            {
                return m_currentPage;
            }
            set
            {
                if (value <= MaxPage && value >= 1)
                    m_currentPage = value;
            }
        }

        private Int32 m_maxPage = 0;
        public Int32 MaxPage
        {
            get
            {
                return m_maxPage;
            }
            private set
            {
                if (value >= 1)
                    m_maxPage = value;
            }
        }

        /// <summary>
        /// Holds our xml data so we dont have to load the document several times from the network
        /// </summary>
        private String XmlData
        {
            get;
            set;
        }
        #endregion
        #endregion

        #region Constructors
        public Guild(String guildName, String realmName, ArmoryRegion region)
        {
            Provider = new SimpleNetworking();
            Region = region;
            GuildName = guildName;
            RealmName = realmName;
        }
        public Guild(String guildName, String realmName, ArmoryRegion region, INetworking provider)
        {
            Provider = provider;
            Region = region;
            GuildName = guildName;
            RealmName = realmName;
        }
        private Guild(String guildUrl, ArmoryRegion region)
        {
            Provider = new SimpleNetworking();
            Region = region;
            GuildUrl = guildUrl;
        }
        private Guild(String guildUrl, ArmoryRegion region, INetworking provider)
        {
            Provider = provider;
            Region = region;
            GuildUrl = guildUrl;
        }
        #endregion

        #region Methods
        public override void Load()
        {
            XmlData = Provider.GetFile(BuildUri(FileName));
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(XmlData);
            XmlNode guildInformation = xmlDoc.SelectSingleNode(XPATH_GUILD_INFO);
            RealmName = guildInformation.Attributes["realm"].Value;
            GuildName = guildInformation.Attributes["name"].Value;
            GuildUrl = guildInformation.Attributes["url"].Value;
            Faction = (Faction)Enum.ToObject(typeof(Faction), Int32.Parse(guildInformation.Attributes["faction"].Value));
            XmlNode dataInformation = xmlDoc.SelectSingleNode(XPATH_GUILD_MEMBER_INFO);
            MemberCount = Int32.Parse(dataInformation.Attributes["memberCount"].Value);
            XmlNodeList characters = xmlDoc.SelectNodes(XPATH_GUILD_CHARACTERS_INFO);
            _Characters(characters);
        }

        private void _Characters(XmlNodeList list)
        {
            if (m_memberList == null)
                m_memberList = new List<DarkAngels.WoW.Library.Armory.Character.Character>(list.Count);

            foreach (XmlNode node in list)
            {
                Character.Character chara = new DarkAngels.WoW.Library.Armory.Character.Character("", "", Region, Provider);
                chara.Class = (Class)Enum.ToObject(typeof(Class), Int32.Parse(node.Attributes["classId"].Value));
                chara.ClassId = Int32.Parse(node.Attributes["classId"].Value);
                chara.Gender = (Gender)Enum.ToObject(typeof(Gender), Int32.Parse(node.Attributes["genderId"].Value));
                chara.GenderId = Int32.Parse(node.Attributes["genderId"].Value);
                chara.Level = Int32.Parse(node.Attributes["level"].Value);
                chara.CharacterName = node.Attributes["name"].Value;
                chara.Race = (Race)Enum.ToObject(typeof(Race), Int32.Parse(node.Attributes["raceId"].Value));
                chara.RaceId = Int32.Parse(node.Attributes["raceId"].Value);
                chara.GuildRank = Int32.Parse(node.Attributes["rank"].Value);
                chara.CharUrl = node.Attributes["url"].Value;
                chara.Faction = Faction;
                chara.FactionId = (int)Faction;
                chara.RealmName = RealmName;
                chara.GuildName = GuildName;
                chara.GuildUrl = GuildUrl;
                chara.Guild = this;

                if (!m_memberList.Contains(chara))
                    m_memberList.Add(chara);
            }
        }
        #endregion
    }
}
